//package com.rxyb.toolize;
//
//import org.apache.logging.log4j.LogManager;
//import org.apache.logging.log4j.Logger;
//
//import javax.crypto.BadPaddingException;
//import javax.crypto.Cipher;
//import javax.crypto.IllegalBlockSizeException;
//import javax.crypto.NoSuchPaddingException;
//import java.io.*;
//import java.security.*;
//import java.security.cert.Certificate;
//import java.security.cert.CertificateException;
//import java.security.cert.CertificateFactory;
//import java.security.interfaces.RSAKey;
//import java.security.interfaces.RSAPrivateKey;
//import java.security.interfaces.RSAPublicKey;
//import java.security.spec.EncodedKeySpec;
//import java.security.spec.InvalidKeySpecException;
//import java.security.spec.PKCS8EncodedKeySpec;
//import java.security.spec.X509EncodedKeySpec;
//import java.util.Base64;
//
///**
// * RSA加解密工具
// *
// * @author flasfr
// * @version 1.1
// */
//public class RsaUtil {
//    private static Logger LOG = LogManager.getLogger(com.rxyb.utils.RsaUtil.class);
//    private static final String TRANS_FORMATION = "RSA/ECB/PKCS1Padding";
//    private static final String SIGNATURE_ALGORITHM = "MD5withRSA";
//    public static final String KEY_ALGORITHM = "RSA";
//    public static final int PUBLIC_KEY = 1;
//    public static final int PRIVATE_KEY = 2;
//
//    /**
//     * 实例公钥
//     */
//    private RSAPublicKey pubKey;
//    /**
//     * 实例私钥
//     */
//    private RSAPrivateKey priKey;
//
//    /**
//     * 创建RsaUtil实例
//     *
//     * @param pubKeyName 公钥文件名 若为空不能公钥加密
//     * @param priKeyName 私钥文件名 若为空私钥解密和签名
//     * @return RsaUtil实例
//     */
//    public static RsaUtil create(String pubKeyName, String priKeyName) throws Exception {
//        RsaUtil inst = new RsaUtil();
//        if (null != pubKeyName) {
//            String pubKey = readKey(pubKeyName);
//            inst.pubKey = (RSAPublicKey) createKey(pubKey, PUBLIC_KEY);
//        }
//        if (null != priKeyName) {
//            String priKey = readKey(priKeyName);
//            inst.priKey = (RSAPrivateKey) createKey(priKey, PRIVATE_KEY);
//        }
//        return inst;
//    }
//
//    /**
//     * 公钥加密
//     *
//     * @param data 明文
//     * @return 密文
//     */
//    public byte[] encrypt(byte[] data) {
//        if (null == pubKey)
//            return null;
//        try {
//            Cipher cipher = Cipher.getInstance(TRANS_FORMATION);
//            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
//            byte[] result = cipher.doFinal(data);
//            return result;
//        } catch (IllegalBlockSizeException ex) {
//            LOG.warn("RSA加密blockSize错误", ex);
//        } catch (BadPaddingException ex) {
//            LOG.warn("RSA加密补位错误", ex);
//        } catch (InvalidKeyException ex) {
//            LOG.warn("RSA加密密钥无效", ex);
//        } catch (NoSuchAlgorithmException ex) {
//            LOG.warn("RSA加密算法不存在", ex);
//        } catch (NoSuchPaddingException ex) {
//            LOG.warn("RSA补位模式不存在", ex);
//        }
//        return null;
//    }
//
//    /**
//     * 私钥解密
//     *
//     * @param data 密文
//     * @return 明文
//     */
//    public byte[] decrpyt(byte[] data) {
//        if (null == priKey)
//            return null;
//        try {
//            Cipher cipher = Cipher.getInstance(TRANS_FORMATION);
//            cipher.init(Cipher.DECRYPT_MODE, priKey);
//            byte[] result = cipher.doFinal(data);
//            return result;
//        } catch (IllegalBlockSizeException ex) {
//            LOG.warn("RSA加密blockSize错误", ex);
//        } catch (BadPaddingException ex) {
//            LOG.warn("RSA加密补位错误", ex);
//        } catch (InvalidKeyException ex) {
//            LOG.warn("RSA加密密钥无效", ex);
//        } catch (NoSuchAlgorithmException ex) {
//            LOG.warn("RSA加密算法不存在", ex);
//        } catch (NoSuchPaddingException ex) {
//            LOG.warn("RSA补位模式不存在", ex);
//        }
//        return null;
//    }
//
//    /**
//     * 使用公钥加密数据
//     *
//     * @param publicKey 公钥串
//     * @param data      原始数据
//     * @return 密文
//     */
//    public static byte[] encrypt(String publicKey, byte[] data) {
//        RSAPublicKey key = (RSAPublicKey) createKey(publicKey, PUBLIC_KEY);
//        try {
//            Cipher cipher = Cipher.getInstance(TRANS_FORMATION);
//            cipher.init(Cipher.ENCRYPT_MODE, key);
//            byte[] result = cipher.doFinal(data);
//            return result;
//        } catch (IllegalBlockSizeException ex) {
//            LOG.warn("RSA加密blockSize错误", ex);
//        } catch (BadPaddingException ex) {
//            LOG.warn("RSA加密补位错误", ex);
//        } catch (InvalidKeyException ex) {
//            LOG.warn("RSA加密密钥无效", ex);
//        } catch (NoSuchAlgorithmException ex) {
//            LOG.warn("RSA加密算法不存在", ex);
//        } catch (NoSuchPaddingException ex) {
//            LOG.warn("RSA补位模式不存在", ex);
//        }
//        return null;
//    }
//
//    /**
//     * 使用公钥加密数据
//     *
//     * @param publicKey 公钥串
//     * @param data      原始数据
//     * @return base64 密文
//     */
//    public static String encrpyt(String publicKey, byte[] data) {
//        byte[] temp = encrypt(publicKey, data);
//        return Base64.getEncoder().encodeToString(temp);
//    }
//
//    /**
//     * 私钥解密
//     *
//     * @param privateKey 私钥串
//     * @param data       密文
//     * @return 原文
//     */
//    public static byte[] decrpyt(final String privateKey, final byte[] data) {
//        RSAPrivateKey key = (RSAPrivateKey) createKey(privateKey, PRIVATE_KEY);
//        try {
//            Cipher cipher = Cipher.getInstance(TRANS_FORMATION);
//            cipher.init(Cipher.DECRYPT_MODE, key);
//            byte[] result = cipher.doFinal(data);
//            return result;
//        } catch (IllegalBlockSizeException ex) {
//            LOG.warn("RSA加密blockSize错误", ex);
//        } catch (BadPaddingException ex) {
//            LOG.warn("RSA加密补位错误", ex);
//        } catch (InvalidKeyException ex) {
//            LOG.warn("RSA加密密钥无效", ex);
//        } catch (NoSuchAlgorithmException ex) {
//            LOG.warn("RSA加密算法不存在", ex);
//        } catch (NoSuchPaddingException ex) {
//            LOG.warn("RSA补位模式不存在", ex);
//        }
//        return null;
//    }
//
//    /**
//     * 私钥解密
//     *
//     * @param privateKey 私钥串
//     * @param data       base64密文
//     * @return 原文
//     */
//    public static byte[] decrpyt(String privateKey, String data) {
//        return decrpyt(privateKey, Base64.getDecoder().decode(data));
//    }
//
//    /**
//     * 私钥做数字签名
//     *
//     * @param privateKey 私钥串
//     * @param data       base64密文
//     * @return
//     */
//    public static String sign(String privateKey, byte[] data) {
//        RSAPrivateKey key = (RSAPrivateKey) createKey(privateKey, PRIVATE_KEY);
//        try {
//            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
//            signature.initSign(key);
//            signature.update(data);
//            return Base64.getEncoder().encodeToString(signature.sign());
//        } catch (NoSuchAlgorithmException e) {
//            LOG.error("签名算法错误", e);
//        } catch (SignatureException e) {
//            LOG.error("签名错误", e);
//        } catch (InvalidKeyException e) {
//            LOG.error("密钥无效", e);
//        }
//        return null;
//    }
//
//    /**
//     * 公钥做验签
//     *
//     * @param publicKey 公钥串
//     * @param data
//     * @param sign
//     * @return
//     */
//    public static boolean verify(String publicKey, byte[] data, String sign) {
//        RSAPublicKey key = (RSAPublicKey) createKey(publicKey, PUBLIC_KEY);
//        try {
//            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
//            signature.initVerify(key);
//            signature.update(data);
//            // 验证签名是否正常
//            return signature.verify(Base64.getDecoder().decode(sign));
//        } catch (NoSuchAlgorithmException e) {
//            LOG.error("签名算法错误", e);
//        } catch (SignatureException e) {
//            LOG.error("签名错误", e);
//        } catch (InvalidKeyException e) {
//            LOG.error("密钥无效", e);
//        }
//        return false;
//    }
//
//    /**
//     * 加载公钥证书
//     *
//     * @param path 证书路径
//     */
//    public static RSAPublicKey readCertKey(String path) {
//        {
//            FileInputStream fi = null;
//            try {
//                CertificateFactory cff = CertificateFactory.getInstance("X.509");
//                fi = new FileInputStream(path);
//                Certificate cf = cff.generateCertificate(fi);
//                return (RSAPublicKey) cf.getPublicKey();
//            } catch (FileNotFoundException ex) {
//                LOG.warn("证书文件不存在", ex);
//            } catch (CertificateException ex) {
//                LOG.warn("证书类型不存在", ex);
//            } finally {
//                if (null != fi) {
//                    try {
//                        fi.close();
//                    } catch (IOException ex) {
//                        LOG.warn("读取证书文件失败", ex);
//                    }
//                }
//            }
//        }
//        return null;
//    }
//
//    /**
//     * 加载公钥证书
//     *
//     * @param classPath 资源路径
//     */
//    public static RSAPublicKey readCertKeyByClassPath(String classPath) {
//        {
//            FileInputStream fi = null;
//            try {
//                CertificateFactory cff = CertificateFactory.getInstance("X.509");
//                InputStream in = ClassLoader.getSystemResourceAsStream(classPath);
//                fi = (FileInputStream) in;
//                Certificate cf = cff.generateCertificate(fi);
//                return (RSAPublicKey) cf.getPublicKey();
//            } catch (CertificateException ex) {
//                LOG.warn("证书类型不存在", ex);
//            } finally {
//                if (null != fi) {
//                    try {
//                        fi.close();
//                    } catch (IOException ex) {
//                        LOG.warn("读取证书文件失败", ex);
//                    }
//                }
//            }
//        }
//        return null;
//    }
//
//    /**
//     * 通过密钥串创建key
//     *
//     * @param key 密钥串
//     * @return 密钥实例
//     */
//    public static RSAKey createKey(String key, int keyType) {
//        try {
//            EncodedKeySpec keySpec = null;
//            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//            if (PUBLIC_KEY == keyType) {
//                keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(key));
//                return (RSAKey) keyFactory.generatePublic(keySpec);
//            } else if (PRIVATE_KEY == keyType) {
//                keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(key));
//                return (RSAKey) keyFactory.generatePrivate(keySpec);
//            }
//        } catch (InvalidKeySpecException ex) {
//            LOG.warn("无效的KeySpec", ex);
//        } catch (NoSuchAlgorithmException ex) {
//            LOG.warn("无效的加解密算法", ex);
//        }
//        return null;
//    }
//
//    /**
//     * 生成RSA密钥对
//     *
//     * @param keyLength 密钥长度
//     * @param savePath  保存路径
//     * @param keyName   密钥名称
//     * @throws Exception 生成异常
//     */
//    public static void rsaKeyGenerator(int keyLength, String savePath, String keyName) throws Exception {
//        // 判断密钥长度
//        if (keyLength < 512)
//            throw new RuntimeException("密钥长度错误，取值需大于512");
//
//        // 滤掉savePath末尾的意外'/'
//        if (savePath.lastIndexOf("/") == savePath.length() - 1)
//            savePath = savePath.substring(0, savePath.length());
//
//        // 生成密钥对儿
//        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); // 创建密钥对生成器
//        kpg.initialize(keyLength); // 指定密钥长度（取值范围：512～2048）
//        KeyPair kp = kpg.genKeyPair(); // 生成密钥对，其中包含着一个公钥和一个私钥的信息
//        RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic(); // 获得公钥
//        RSAPrivateKey privateKey = (RSAPrivateKey) kp.getPrivate(); // 获得私钥
//
//        // 保存公钥和私钥
//        saveKey(savePath + "/" + keyName + "_pub.key", publicKey);// 保存公钥
//        saveKey(savePath + "/" + keyName + "_pri.key", privateKey);// 保存私钥
//    }
//
//    private static void saveKey(String path, RSAKey key) {
//
//        ObjectOutputStream ooStream = null;
//        try {
//            FileOutputStream outStream = new FileOutputStream(path);
//            ooStream = new ObjectOutputStream(outStream);
//            ooStream.writeObject(key);
//        } catch (IOException ex) {
//            LOG.warn("密钥保存失败", ex);
//        } finally {
//            if (null != ooStream) {
//                try {
//                    ooStream.close();
//                } catch (IOException ex) {
//                    LOG.warn("密钥保存失败", ex);
//                }
//            }
//        }
//    }
//
//    /**
//     * 从文件读取密钥
//     *
//     * @param path 文件路径
//     * @return 密钥
//     * @throws Exception
//     */
//    public static String readKey(String path) throws Exception {
//        InputStream in = new FileInputStream(path);
//        ObjectInputStream inStream = new ObjectInputStream(in);
//        Object readObject = inStream.readObject();
//        in.close();
//        return Base64.getEncoder().encodeToString(((Key) readObject).getEncoded());
//    }
//
//    /**
//     * 从文件读取密钥
//     *
//     * @param classPath 资源路径
//     * @return 密钥
//     * @throws Exception
//     */
//    public static String readKeyByClassPath(String classPath) throws Exception {
//        InputStream in = ClassLoader.getSystemResourceAsStream(classPath);
//        ObjectInputStream inStream = new ObjectInputStream(in);
//        Object readObject = inStream.readObject();
//        in.close();
//        return Base64.getEncoder().encodeToString(((Key) readObject).getEncoded());
//    }
//}
